package ru.nsu.fit.iconveyor.example.math.node;

import ru.nsu.fit.iconveyor.conveyor.node.InnerNode;
import ru.nsu.fit.iconveyor.conveyor.node.NodeConnection;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class AdditionNode extends InnerNode {
    public static final String INPUT_ARG_1 = "input_arg_1";
    public static final String INPUT_ARG_2 = "input_arg_2";
    public static final String OUTPUT_RESULT = "output_result";

    private final NodeConnection<Double> inputArg1;
    private final NodeConnection<Double> inputArg2;
    private final NodeConnection<Double> outputResult;

    public AdditionNode(String id) {
        super(id);

        inputArg1 = new NodeConnection<Double>(Double.class, NodeConnection.Type.INPUT, INPUT_ARG_1);
        inputArg2 = new NodeConnection<Double>(Double.class, NodeConnection.Type.INPUT, INPUT_ARG_2);
        outputResult = new NodeConnection<Double>(Double.class, NodeConnection.Type.OUTPUT, OUTPUT_RESULT);

        addNodeConnection(inputArg1);
        addNodeConnection(inputArg2);
        addNodeConnection(outputResult);
    }

    @Override
    public Map<String, Object> execute(Map<String, Object> resource, Properties prop) {
        Map<String, Object> inputBundles = resource;

        Double arg1 = (Double)inputBundles.get(inputArg1.getName());
        Double arg2 = (Double)inputBundles.get(inputArg2.getName());

        double result = arg1 + arg2;

        // Generate result
        Map<String, Object> outputBundles = new HashMap<String, Object>();
        outputBundles.put(outputResult.getName(), result);
        return outputBundles;
    }

    @Override
    public Map<String, Object> preExecute(Map<String, Object> availableInputResource, Properties prop) {
        Map<String, Object> inputBundles = availableInputResource;

        if (inputBundles.get(inputArg1.getName()) == null || inputBundles.get(inputArg2.getName()) == null) {
            return null;
        }

        return availableInputResource;
    }

    @Override
    public int getOutputToInputRatio() {
        return 1;
    }
}
